/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.csp.sentinel.slots.block.authority;

import com.alibaba.csp.sentinel.context.Context;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.util.StringUtil;

/**
 * Rule checker for white/black list authority.
 *
 * @author Eric Zhao
 * @since 0.2.0
 */
final class AuthorityRuleChecker {

    static boolean passCheck(AuthorityRule rule, Context context) {
        String requester = context.getOrigin();//获取当先上下文的origin值
        // Empty origin or empty limitApp will pass.
        if (StringUtil.isEmpty(requester) || StringUtil.isEmpty(rule.getLimitApp())) {//判断origin为空 或则规则限制的app集合为空
            return true; //返回校验通过
        }
        // Do exact match with origin name. 从limitApp字符串中找出origin值的位置
        int pos = rule.getLimitApp().indexOf(requester);
        boolean contain = pos > -1; //判断limitApp字符串中是否包含origin值
        if (contain) {//如果包含
            boolean exactlyMatch = false;
            String[] appArray = rule.getLimitApp().split(",");//将limitApp按照逗号切割
            for (String app : appArray) {//遍历切割的数组
                if (requester.equals(app)) {//判断当前遍历的app是否与origin值相等
                    exactlyMatch = true;
                    break;
                }
            }
            contain = exactlyMatch;
        }
        int strategy = rule.getStrategy();//获取规则类型
        if (strategy == RuleConstant.AUTHORITY_BLACK && contain) {//当前规则为黑名单规则，并且origin的值属于黑名单内
            return false; //直接返回校验失败
        }
        if (strategy == RuleConstant.AUTHORITY_WHITE && !contain) {//当前规则为摆明单规则，并且origin的值不属于白名单内
            return false;//直接返回校验失败
        }
        return true;//直接返回校验通过
    }

    private AuthorityRuleChecker() {}
}
